package com.jic.order.impl;

import com.alibaba.fastjson.JSONObject;
import com.jic.common.base.vo.Page;
import com.jic.common.base.vo.RestResult;
import com.jic.order.api.PayOrderToInteractionApi;
import com.jic.order.entity.OrderParent;
import com.jic.order.entity.OrderPay;
import com.jic.order.entity.OrderPayDetail;
import com.jic.order.mapper.OrderPayMapper;
import com.jic.common.base.vo.PageResult;
import com.jic.order.request.PayOrderRequest;
import com.jic.order.service.OrderParentService;
import com.jic.order.service.OrderPayDetailService;
import com.jic.order.service.OrderPayService;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import com.jic.order.service.OrderService;
import com.jic.order.utils.DatagramEncDec;
import com.jic.order.utils.HttpUtil;
import com.jic.order.utils.XmlUtils;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * description: OrderPayServiceImpl date: 2020-02-11 14:12 author: wangys version: 1.0
 */
@Service
@Slf4j
public class OrderPayServiceImpl implements OrderPayService {

	@Autowired(required=false)
	private  OrderPayMapper orderPayMapper;

	@Autowired(required=false)
	private PayOrderToInteractionApi payOrderToInteractionApi;
	@Autowired
	private OrderService orderService;
	@Autowired
	private OrderParentService orderParentService;
	@Autowired
	private OrderPayDetailService orderPayDetailService;

	@Override
	public long insert(OrderPay orderPay) {
		return 0;
	}

	@Override
	public long delete(Long id) {
		return 0;
	}

	@Override
	public long update(OrderPay orderPay) {
		return 0;
	}

	@Override
	public OrderPay queryByPrimaryKey(Long id) {
		return null;
	}

	@Override
	public List<OrderPay> query(OrderPay orderPay) {
		return orderPayMapper.query(orderPay);
	}

	@Override
	public PageResult<OrderPay> queryPage(OrderPay orderPay, Page pageQuery) {
		return null;
	}

	/**
	 * 支付
	 * 0微众支付 1微信支付
	 * @param payOrderRequest
	 * @return
	 */
	@Override
	public RestResult<Map<String,String>> payOrder(PayOrderRequest payOrderRequest) {

		List<JSONObject> mOrders = orderService.queryOrderByOrderNo(payOrderRequest.getParentOrderNo());
		JSONObject m_order = mOrders.get(0);

		Integer status = m_order.getInteger("order_type");
		Integer flag = 2;
		if(41==status || 11==status){
			flag = 4;
		}
		//主订单修改为成功
		OrderParent parent = new OrderParent();
		parent.setParentOrderNo(payOrderRequest.getParentOrderNo());
		parent.setOrderStatus(flag);//已支付
		orderParentService.update(parent);
		JSONObject pa = new JSONObject();
		pa.put("parentOrderNo",payOrderRequest.getParentOrderNo());
		pa.put("status",flag);
		orderService.updateByOrderNo(pa);
		if(null==payOrderRequest.getWay() || 0==payOrderRequest.getWay() ){
			return wxPay(payOrderRequest);//微信
		}else {
			return RestResult.success(new HashMap<>());
		}
//		Integer way = payOrderRequest.getWay();
//		switch (way){
//			case 0: return wxPay(payOrderRequest);//微信
//			case 1: return wzPay(payOrderRequest);//微众
//			default: return wxPay(payOrderRequest);//微信
//		}
	}

	@Override
	public RestResult<JSONObject> prePayOrderCheck(PayOrderRequest payOrderRequest) {
		JSONObject preOrderParam = new JSONObject();
		preOrderParam.put("bizSeqNo",UUID.randomUUID().toString().replaceAll("-",""));
		preOrderParam.put("orderNo",payOrderRequest.getParentOrderNo());
		preOrderParam.put("merchantId","101000109937526");
		preOrderParam.put("webankAppid","W6650122");
		preOrderParam.put("productCode","we2000");
		preOrderParam.put("userId","11");
		preOrderParam.put("payType","08");
		preOrderParam.put("clientIp","127.0.0.1");
		preOrderParam.put("deviceId","123");
		preOrderParam.put("osType","1");
		preOrderParam.put("custom","2");
		preOrderParam.put("openid","orVYg5e_E2d3gj1OUsg4Cv_74NuA");
		preOrderParam.put("unionid","ABCQQ0421193646");
		RestResult<JSONObject> result = payOrderToInteractionApi.wzPayCheck(preOrderParam);
		return result;
	}

	/**
	 * 退款
	 * @param payOrderRequest
	 * @return
	 */
	@Override
	public RestResult<JSONObject> refundOrder(PayOrderRequest payOrderRequest) {
		JSONObject preOrderParam = new JSONObject();
		preOrderParam.put("bizSeqNo",UUID.randomUUID().toString().replaceAll("-",""));
		preOrderParam.put("refundOrderNo",UUID.randomUUID().toString().replaceAll("-",""));
		preOrderParam.put("merchantId","101000109937526");
		preOrderParam.put("orderNo",payOrderRequest.getParentOrderNo());
		preOrderParam.put("amount","1");
		preOrderParam.put("webankAppid","W6650122");
		preOrderParam.put("refundOrderNo","1");
		RestResult<JSONObject> result = payOrderToInteractionApi.refundOrder(preOrderParam);
		refundOrderCheck(payOrderRequest);
		return result;
	}
	/**
	 * 退款查询
	 * @param payOrderRequest
	 * @return
	 */
	@Override
	public RestResult<JSONObject> refundOrderCheck(PayOrderRequest payOrderRequest) {
		JSONObject preOrderParam = new JSONObject();
		preOrderParam.put("bizSeqNo",UUID.randomUUID().toString().replaceAll("-",""));
		preOrderParam.put("merchantId","101000109937526");
		preOrderParam.put("orderNo",payOrderRequest.getParentOrderNo());
		preOrderParam.put("refundOrderNo","1");
		preOrderParam.put("webankAppid","W6650122");
		preOrderParam.put("transType","1");
		RestResult<JSONObject> result = payOrderToInteractionApi.refundOrderCheck(preOrderParam);
		return result;
	}

	@Override
	public RestResult<JSONObject> getPwd(JSONObject jsonObject) {
		JSONObject preOrderParam = new JSONObject();
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("YYYYmmddHHMMssSSS");
		preOrderParam.put("bizSeqNo",UUID.randomUUID().toString().replaceAll("-",""));
		preOrderParam.put("from","1");
		preOrderParam.put("version","10.0");
		preOrderParam.put("platTimeStamp",simpleDateFormat.format(new Date()));
		preOrderParam.put("channelId","18");
		preOrderParam.put("openid","orVYg5e_E2d3gj1OUsg4Cv_74NuA");
		preOrderParam.put("unionid","ABCQQ0421193646");
//		preOrderParam.put("cardNo","6236330037800269521");
		RestResult<JSONObject> restResult =  payOrderToInteractionApi.getPwdFactor(preOrderParam);
		if(null==restResult || null==restResult.getData()){
			return null;
		}
		return restResult;
	}

	/**
	 * 微众支付
	 * 1.预下单
	 * 2.支付
	 * 3.登台同步结果处理业务
	 * @param payOrderRequest
	 * @return
	 */
	private RestResult<Map<String,String>> wzPay(PayOrderRequest payOrderRequest){
		String parentOrderNo = payOrderRequest.getParentOrderNo();
		JSONObject parentOrder =  orderParentService.queryOrderParentByOrderNo(parentOrderNo);
		Integer status =  parentOrder.getInteger("order_status");
		if(1!=status){
			return RestResult.error("0001","此状态无法支付");
		}
		//预下单
		JSONObject result  = toPrePayOrder(payOrderRequest);
		if(null == result){
			return RestResult.error("0001","下单失败请从新下单");
		}
		String code = result.getString("code");
		String msg = result.getString("msg");
		Long mills = System.currentTimeMillis();
		String pay_order_no = "pay"+mills;
		OrderPayDetail orderPayDetail = null;
		if("11350000".equals(code) || "11352008".equals(code)){
			if(parentOrder==null){
				return RestResult.error("0001","订单不存在");
			}
			OrderPay orderPay = new OrderPay();
			orderPay.setParentOrderNo(parentOrderNo);
			orderPay.setPayStatus(1);
			orderPay.setPayTotalAmount(parentOrder.getBigDecimal("actual_pay_total_amount"));
			orderPay.setOrderPayNo(pay_order_no);
			orderPay.setCreateTime(new Date());
			orderPay.setDeleteFlag(false);
			orderPay.setPayType(1);
			orderPay.setPayTime(new Date());
			orderPay.setUpdateTime(new Date());
			orderPay.setLavePayTotalAmount(new BigDecimal(0));
			//插入付款表
			orderPayMapper.insert(orderPay);
			//插入详细步骤表
			orderPayDetail = new OrderPayDetail();
			orderPayDetail.setDeleteFlag(false);
			orderPayDetail.setOrderPayNo(pay_order_no);
			orderPayDetail.setPayStatus(1);
			orderPayDetail.setPayWay(3);
			orderPayDetail.setPayAmount(orderPay.getPayTotalAmount());
			orderPayDetail.setPayAskNo(mills.toString());
			orderPayDetail.setPayAskTime(new Date());
			orderPayDetail.setUpdateTime(new Date());
			orderPayDetail.setWzStep(1);
			orderPayDetailService.insert(orderPayDetail);
		}else {
			return RestResult.error("0001",msg);
		}
		log.info("预下单结果:{}",result);
		result.clear();
		result.clear();  //
		result = toPayOrder(payOrderRequest,new BigDecimal("1"));
		if(null == result || !"11350000".equals(result.getString("code"))){
			return RestResult.error("0001",result.getString("desc"));
		}
		//步骤改为预付款
		orderPayDetail.setWzStep(2);
		orderPayDetailService.update(orderPayDetail);
		log.info("预支付:{}",result);
		return RestResult.success (new HashMap<>());
	}


	/**
	 * 获取卡密
//	 * @param payOrderRequest
	 * @return
	 */
	private JSONObject toPwd(PayOrderRequest payOrderRequest){
		JSONObject preOrderParam = new JSONObject();
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("YYYYmmddHHMMssSSS");
		preOrderParam.put("bizSeqNo",UUID.randomUUID().toString().replaceAll("-",""));
		preOrderParam.put("from",payOrderRequest.getFrom());
		preOrderParam.put("version","10.0");
		preOrderParam.put("platTimeStamp",simpleDateFormat.format(new Date()));
		preOrderParam.put("channelId","18");
		preOrderParam.put("openid","orVYg5e_E2d3gj1OUsg4Cv_74NuA");
		preOrderParam.put("unionid","3Jj0vmOCBcu4P7cK8g6acQb8b");
//		preOrderParam.put("cardNo","6236330037800269521");
		RestResult<JSONObject> restResult =  payOrderToInteractionApi.getPwdFactor(preOrderParam);
		if(null==restResult || null==restResult.getData()){
			return null;
		}
		return restResult.getData();
	}

	/**
	 * 支付
	 * @param payOrderRequest
	 * @return
	 */
	private JSONObject toPayOrder(PayOrderRequest payOrderRequest,BigDecimal amount){
		JSONObject preOrderParam = new JSONObject();
		preOrderParam.put("bizSeqNo",UUID.randomUUID().toString().replaceAll("-",""));
		preOrderParam.put("orderNo",payOrderRequest.getParentOrderNo());
		preOrderParam.put("notifyType","HTTP");
		preOrderParam.put("productCode","101163");
		preOrderParam.put("amount",new BigDecimal("1"));
		preOrderParam.put("payType","08");
		preOrderParam.put("checkPasswordFlag","1");
		preOrderParam.put("password",payOrderRequest.getPwd());
		preOrderParam.put("pwdFactor",payOrderRequest.getNoce());
		preOrderParam.put("channelId","ACQECP00000001");
		preOrderParam.put("merchantId","101000109937526");
		preOrderParam.put("webankAppid","W6650122");
		preOrderParam.put("userId","11");
		preOrderParam.put("clientIp","127.0.0.1");
		preOrderParam.put("deviceId","123");
		preOrderParam.put("sceneFlag","N");
		preOrderParam.put("osType","1");
		preOrderParam.put("custom","2");
		preOrderParam.put("openid","orVYg5e_E2d3gj1OUsg4Cv_74NuA");
		preOrderParam.put("unionid","ABCQQ0421193646");
		preOrderParam.put("partnerId","100000");
		RestResult<JSONObject> restResult =  payOrderToInteractionApi.wzPay(preOrderParam);
		if(null==restResult || null==restResult.getData()){
			return null;
		}
		return restResult.getData();
	}

	private JSONObject toPrePayOrder(PayOrderRequest payOrderRequest){
		Number amount = 1.00;
		JSONObject preOrderParam = new JSONObject();
		preOrderParam.put("bizSeqNo","11111111111111111111111111111111");
		preOrderParam.put("orderNo",payOrderRequest.getParentOrderNo());
		preOrderParam.put("merchantId","101000109937526");
		preOrderParam.put("userId","11");
		preOrderParam.put("webankAppid","W6650122");
		preOrderParam.put("amount",new BigDecimal("1.00"));
		preOrderParam.put("clientIp","139.217.228.165");
		preOrderParam.put("deviceId","123");
		preOrderParam.put("osType","1");
		preOrderParam.put("custom","2");
		preOrderParam.put("openid","orVYg5e_E2d3gj1OUsg4Cv_74NuA");
		preOrderParam.put("unionid","ABCQQ0421193646");
		preOrderParam.put("partnerId","100000");
		preOrderParam.put("productCode","100000");
		preOrderParam.put("payType","08");
		//preOrderParam.put("goodList",null);
		RestResult<JSONObject> restResult =  payOrderToInteractionApi.prePayOrder(preOrderParam);
		if(null==restResult || null==restResult.getData()){
			return null;
		}
		return restResult.getData();
	}

	/**
	 * 微信支付
	 * 1.支付
	 * 2.等待微信异步回调处理业务
	 * @param payOrderRequest
	 * @return
	 */
	private RestResult<Map<String,String>> wxPay(PayOrderRequest payOrderRequest)  {
		String parentOrderNo = payOrderRequest.getParentOrderNo();
		JSONObject parentOrder =  orderParentService.queryOrderParentByOrderNo(parentOrderNo);
		Map<String,String> result = new HashMap<>();
		String nonce_str = UUID.randomUUID().toString().replaceAll("-","");
		Map<String, String> packageParams = new HashMap<String, String>();
		String appid  = "wx6fb4d5b499965d96";
		String mch_id  = "1604557393";
		String key = "bc7230deeb01a357ccd249c714b41d4c";
		packageParams.put("appid", appid);
		packageParams.put("mch_id", mch_id);
		packageParams.put("nonce_str", nonce_str);
		packageParams.put("body","商品付款详情");
		packageParams.put("out_trade_no", payOrderRequest.getParentOrderNo());//商户订单号
		packageParams.put("total_fee",parentOrder.getBigDecimal("actual_pay_total_amount")+"");//支付金额，这边需要转成字符串类型，否则后面的签名会失败
		packageParams.put("total_fee","1");//支付金额，这边需要转成字符串类型，否则后面的签名会失败
		packageParams.put("spbill_create_ip",payOrderRequest.getIp());
		packageParams.put("notify_url","https://wbrest.dreamane.com/jic-order/callback/wxPay");//支付成功后的回调地址
		packageParams.put("trade_type", "JSAPI");//支付方式
		packageParams.put("openid",payOrderRequest.getOpenId());
		String params  = createLinkString(packageParams);
		params = params+"&key="+ key;
		String mysign = DatagramEncDec.sign(params,"UTF-8");
		String xml = toXml(mysign,packageParams);
		String resultStr = HttpUtil.sendJsonPost("https://api.mch.weixin.qq.com/pay/unifiedorder",xml);
		log.info("微信预下单同步返回结果"+resultStr);
		Map<String,String> prePayResult = null;
		try {
			prePayResult = XmlUtils.doXMLParse(resultStr);
		} catch (Exception e) {
			e.printStackTrace();
		}
		String  return_code = prePayResult.get("return_code");
		Long timeStamp = System.currentTimeMillis() / 1000;
		if("SUCCESS".equals(return_code)){
			String prepay_id = prePayResult.get("prepay_id");//返回的预付单信息
			String stringSignTemp = "appId=" +appid +
					"&nonceStr=" + nonce_str + "&package=prepay_id=" + prepay_id+
					"&signType=MD5&timeStamp=" + timeStamp+"&key="+key;
			log.info("原串:{}",stringSignTemp);
			String paySign = DatagramEncDec.sign(stringSignTemp,"UTF-8");
			result.put("nonceStr",nonce_str);
			result.put("package", "prepay_id=" + prepay_id);
			result.put("timeStamp", timeStamp + "");
			result.put("paySign", paySign);
			result.put("prepay_id",prepay_id);
			log.info("返回小程序支付:{}",result);
			return RestResult.success(result);
		}
		return RestResult.success(new HashMap<>());
	}

	private String toXml(String sign,Map<String,String> map){
		String xml = "<xml>" + "<appid>" + map.get("appid") + "</appid>"
				+ "<body><![CDATA[" +  map.get("body") + "]]></body>"
				+ "<mch_id>" +map.get("mch_id") + "</mch_id>"
				+ "<nonce_str>" + map.get("nonce_str") + "</nonce_str>"
				+ "<notify_url>" +  map.get("notify_url") + "</notify_url>"
				+ "<openid>" + map.get("openid") + "</openid>"
				+ "<out_trade_no>" + map.get("out_trade_no") + "</out_trade_no>"
				+ "<spbill_create_ip>" + map.get("spbill_create_ip") + "</spbill_create_ip>"
				+ "<total_fee>" + map.get("total_fee") + "</total_fee>"
				+ "<trade_type>" + map.get("trade_type") + "</trade_type>"
				+ "<sign>" + sign + "</sign>"
				+ "</xml>";
			return xml;
	}

	private String createLinkString(Map<String,String> params){
		List<String> keys = new ArrayList<String>(params.keySet());
		Collections.sort(keys);
		String prestr = "";
		for (int i = 0; i < keys.size(); i++) {
			String key = keys.get(i);
			String value = params.get(key);
			if (i == keys.size() - 1) {// 拼接时，不包括最后一个&字符
				prestr = prestr + key + "=" + value;
			} else {
				prestr = prestr + key + "=" + value + "&";
			}
		}
		return prestr;
	}

}
